﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TP2.Lib;

namespace TP2.Lib
{
     [Serializable]
    public class MovimientoLineal : TrayectoriaAbstracta
    {

        #region /*-------- Propiedades ---------------*/

        private double[] _posicionInicial = new double[3];
        public double[] PosicionInicial
        {
            get { return this._posicionInicial; }
            set { this._posicionInicial = value;}
        }

        private double[] _posicionFinal = new double[3];
        public double[] PosicionFinal
        {
            get { return this._posicionFinal; }
            set { this._posicionFinal = value; }
        }

        private double _velocidadX;
        public double VelocidadX
        {
            get { return this._velocidadX; }
            set { this._velocidadX = value;}
        }

        private double _velocidadY;
        public double VelocidadY
        {
            get { return this._velocidadY; }
            set { this._velocidadY = value; }
        }

        #endregion

        private MovimientoLineal() { } /*Constructor vacio, utilizado solo por el serializador*/

        public MovimientoLineal(double[] posicionInicial, double[] posicionFinal, int rapidez)
        {
            this.PosicionInicial = posicionInicial;
            this.PosicionFinal = posicionFinal;
            this.CalcularVelocidades(rapidez);
        }

        public MovimientoLineal(double[] posicionInicial, int rebotes, ElementoJuego elemento)
        {
            double[] posicionFinal = new double[3];
            posicionFinal[0] = elemento.Dimensiones[0];
            posicionFinal[1] = Math.Ceiling((elemento.Dimensiones[1]) / System.Convert.ToDouble(rebotes));
            this.PosicionInicial = posicionInicial;
            this.CalcularVelocidadesBombardero(elemento.Rapidez, rebotes);
        }

        public override double[] GetSiguientePunto(double[] posicion)
        {
            double[] posicionNueva = new double[3];

            posicionNueva[0] = posicion[0] + this.VelocidadX;
            posicionNueva[1] = posicion[1] + this.VelocidadY;
            return (posicionNueva);

        }

        #region --------------- Metodos Privados ---------------

        private void CalcularVelocidades(int rapidez)
        {
            double DeltaX;
            double DeltaY;
            double Tangente;
            double VX;
            double VY;

            DeltaY = this.PosicionFinal[1] - this.PosicionInicial[1]; // Y1-Y0
            DeltaX = this.PosicionFinal[0] - this.PosicionInicial[0]; // X1-X0

            if (DeltaX == 0)
            {
                if (DeltaY == 0)
                {
                    //Caso especial que el ElementoDelJuego no se mueva
                    VX = 0;
                    VY = 0;
                }
                else
                {
                    if (DeltaY > 0)
                    {
                        //Movimiento Vertical positivo
                        VX = 0;
                        VY = rapidez;
                    }
                    else
                    {
                        //Movimiento Vertical negativo
                        VX = 0;
                        VY = rapidez * (-1);
                    }
                }
            }
            else
            {
                ///Caso general que el ElementoDelJuego se mueva en linea recta
                
                Tangente = (DeltaY / DeltaX);
                VX = (rapidez) * (1 / Math.Sqrt((1 + Math.Pow(Tangente, 2)))); // Cambie Vy por Vx
                VY = (rapidez) * (Tangente / Math.Sqrt((1 + Math.Pow(Tangente, 2)))); //Idem

                if (((Tangente > 0) & (DeltaX < 0)) | ((Tangente < 0) & (DeltaY > 0)))
                {
                    ///Salvo la indeterminacion de 180 grados analizando simultaneamente el signo de la Tangente y del Delta para restringirme a un cuadrante. 
                    VX = -1 * VX;
                    VY = -1 * VY;
                }
            }

            this.VelocidadX = VX;
            this.VelocidadY = VY;
        }

        private void CalcularVelocidadesBombardero(int rapidez,int rebotes)
        {
            double DeltaX;
            double DeltaY;
            double Tangente;
            double VX;
            double VY;

            DeltaY = this.PosicionFinal[1] - this.PosicionInicial[1]; // Y1-Y0
            DeltaX = this.PosicionFinal[0] - this.PosicionInicial[0]; // X1-X0

            if (DeltaX == 0)
            {
                if (DeltaY == 0)
                {
                    //Caso especial que el ElementoDelJuego no se mueva
                    VX = 0;
                    VY = 0;
                }
                else
                {
                    //Movimiento Horizontal
                    VX = rapidez;
                    VY = 0;
                }
            }
            else
            {
                //Caso general que el ElementoDelJuego se mueva en linea recta

                Tangente = (DeltaY / DeltaX);
                Tangente = Tangente * rebotes;
                VY = (rapidez) * (1 / Math.Sqrt((1 + Math.Pow(Tangente, 2))));
                VX = (rapidez) * (Tangente / Math.Sqrt((1 + Math.Pow(Tangente, 2))));
            }

            this.VelocidadX = VX;
            this.VelocidadY = VY;
        }

        #endregion
    }
}
